import axios from 'axios'
import qs from 'qs'
import config from '@/config'
import { Dialog, Toast } from 'antd-mobile'
import jsCookies from 'js-cookie'
const baseURL = process.env.NODE_ENV === 'development' ? config.baseUrl.dev : config.baseUrl.pro
import {
  useNavigate
} from 'react-router-dom'
let loading

function startLoading () { // 加载开始动画
  loading = Toast.show({
    icon: 'loading',
    content: '加载中…',
  })
}
function endLoading () { // 加载结束动画
  loading?.close()
}

function toGrant () { // 是否跳转登录页面
  const navigate = useNavigate()
  Dialog.confirm({
    title: '提示',
    content: '请先登录',
    closeOnAction: true,
    onCancel: async () => {
      navigate(-1)
    },
    onConfirm: async () => {
      navigate(`${config.routeBaseUrl}login`)
    }
  })
}

function getInsideConfig () { // 这个函数负责返回基础配置的参数
  const config = {
    baseURL,
    headers: {
      //
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    // 允许跨域携带cookie
    withCredentials: true,
    transformRequest: [params => qs.stringify(params)]
  }
  return config
}

// 用户登录信息相关错误(返回当前的状态码)
/**
 * 10:用户没有登录
 * 11:用户登录失效
 * 12:请先获取验证码
 * 13:验证码错误
 * 14:未绑定账号
 * 15:手机号已注册
 */
const USER_ERROR = [10, 11, 12, 13, 14]

/**
 *
 * check：是否传token  //  这个相当于token
 * loading：是否显示loading加载
 * tip：是否前往登录
 * status：预期返回的 状态码
 * statusFun: 根据预期返回的状态码执行相对应的函数
 * requestinterceptors: {
 *    requestInterceptor: () => {} 这个是某个请求单独定制请求拦截
 *    responseInterceptor: （） => {} 这个是某个请求单独定制响应拦截
 * }
 * */

/* eslint-disable */
function interceptors( instance ) { //instance 就是axios 在request中被赋值了  此处请求拦截 和 响应
  const { check, loading, tip, status, statusFun, requestinterceptors } = inoptions
  // 请求拦截
  instance.interceptors.request.use(config => {
    //加载动画的开启
    loading && startLoading()
    // 需要校验token 修改头部
    if (check){
      let token = jsCookies.get('_ticket') || ''
      config.headers.ticket = token
    }
    // end
    // 单个请求拦截回调
    if (requestinterceptors && requestinterceptors.requestInterceptor) {
      requestinterceptors.requestInterceptor(config)
    }
    return config
  }, error => {
    return Promise.reject(error)
  })


  // 响应拦截
  instance.interceptors.response.use(({data}) => {
    const { code } = data
    //加载结束的动画
    loading && endLoading() 
    if (USER_ERROR.includes(code)) {
      tip && toGrant() // 'token值无效，请重新登录'
      jsCookies.remove('_ticket')
    }
    // 单个响应拦截回调
    if (requestinterceptors && requestinterceptors.responseInterceptor) {
      requestinterceptors.responseInterceptor(data)
    }
    return data
  }, error => {
    console.log(error)
    Toast.show({
      icon: 'fail',
      content: error.response.data,
    })
    const { status } = error.response
    if (USER_ERROR.includes(status)) {
      tip && toGrant() // 'token值无效，请重新登录'
      jsCookies.remove('_ticket')
    }
    return Promise.reject(error)
  })
}

/**
 * inoptions : axios中的相关参数 data url header等
 * check：是否传ticket  //  这个相当于token
 * loading：是否显示loading加载
 * tip：是否前往登录
 * status：预期返回的 状态码 
 * statusFun: 根据预期返回的状态码执行相对应的函数
 * requestinterceptors: {
 *    requestInterceptor: () => {} 这个是某个请求单独定制请求拦截
 *    responseInterceptor: （） => {} 这个是某个请求单独定制响应拦截
 * }
 * */
// 参数配置默认值
let inoptions = { check: true, loading: true, tip: true, status: [], statusFun: () => { } }
/* eslint-disable */
function request( config = {} ) {
  const instance = axios.create(Object.assign(getInsideConfig(), config))  // 此处获取实例
  interceptors(instance) // interceptors这个是响应和请求拦截函数
  return (axiosData) => {
    inoptions = Object.assign(inoptions, axiosData) // 最终的参数配置
    return instance(axiosData)
  }
}

export default request